/**
 * 数据验证工具
 * 提供数据验证和模式检查功能
 */

/**
 * 验证数据是否符合模式
 * @param {Object} data - 要验证的数据
 * @param {Object} schema - 验证模式
 * @returns {Object} 验证结果
 */
export function validateData(data, schema) {
  const errors = []
  let isValid = true

  try {
    // 检查必填字段
    if (schema.required) {
      schema.required.forEach(field => {
        if (!data.hasOwnProperty(field) || data[field] === undefined || data[field] === null) {
          errors.push({
            field,
            message: `${field} 是必填字段`,
          })
          isValid = false
        }
      })
    }

    // 如果必填字段已经有错误，不再继续验证其他规则
    if (!isValid) {
      return {
        isValid,
        errors,
      }
    }

    // 验证每个字段的规则
    Object.keys(schema.properties || {}).forEach(field => {
      const value = data[field]
      const rules = schema.properties[field]

      // 如果字段值不存在，但不是必填，跳过验证
      if (value === undefined || value === null) {
        if (rules.default !== undefined) {
          // 设置默认值
          data[field] = rules.default
        }
        return
      }

      // 类型验证
      if (rules.type && !validateType(value, rules.type)) {
        errors.push({
          field,
          message: `${field} 必须是 ${rules.type} 类型`,
        })
        isValid = false
      }

      // 最小长度验证
      if (rules.minLength && typeof value === 'string' && value.length < rules.minLength) {
        errors.push({
          field,
          message: `${field} 长度不能小于 ${rules.minLength}`,
        })
        isValid = false
      }

      // 最大长度验证
      if (rules.maxLength && typeof value === 'string' && value.length > rules.maxLength) {
        errors.push({
          field,
          message: `${field} 长度不能大于 ${rules.maxLength}`,
        })
        isValid = false
      }

      // 最小值验证
      if (rules.min !== undefined && typeof value === 'number' && value < rules.min) {
        errors.push({
          field,
          message: `${field} 不能小于 ${rules.min}`,
        })
        isValid = false
      }

      // 最大值验证
      if (rules.max !== undefined && typeof value === 'number' && value > rules.max) {
        errors.push({
          field,
          message: `${field} 不能大于 ${rules.max}`,
        })
        isValid = false
      }

      // 正则表达式验证
      if (rules.pattern && typeof value === 'string' && !rules.pattern.test(value)) {
        errors.push({
          field,
          message: `${field} 格式不正确`,
        })
        isValid = false
      }

      // 枚举值验证
      if (rules.enum && !rules.enum.includes(value)) {
        errors.push({
          field,
          message: `${field} 必须是以下值之一: ${rules.enum.join(', ')}`,
        })
        isValid = false
      }

      // 自定义验证函数
      if (rules.validator && typeof rules.validator === 'function') {
        const customError = rules.validator(value, data)
        if (customError) {
          errors.push({
            field,
            message: customError,
          })
          isValid = false
        }
      }

      // 对象验证
      if (rules.properties && typeof value === 'object' && !Array.isArray(value)) {
        const nestedValidation = validateData(value, rules)
        if (!nestedValidation.isValid) {
          nestedValidation.errors.forEach(error => {
            errors.push({
              field: `${field}.${error.field}`,
              message: error.message,
            })
          })
          isValid = false
        }
      }

      // 数组验证
      if (rules.items && Array.isArray(value)) {
        value.forEach((item, index) => {
          const itemValidation = validateData(item, { properties: rules.items })
          if (!itemValidation.isValid) {
            itemValidation.errors.forEach(error => {
              errors.push({
                field: `${field}[${index}].${error.field}`,
                message: error.message,
              })
            })
            isValid = false
          }
        })
      }
    })

    return {
      isValid,
      errors,
      data, // 返回可能包含默认值的数据
    }
  } catch (error) {
    console.error('数据验证过程中发生错误:', error)
    return {
      isValid: false,
      errors: [{ field: 'general', message: '验证过程发生错误' }],
    }
  }
}

/**
 * 验证数据类型
 * @param {*} value - 要验证的值
 * @param {string} type - 预期类型
 * @returns {boolean} 是否通过验证
 */
function validateType(value, type) {
  switch (type) {
    case 'string':
      return typeof value === 'string'
    case 'number':
      return typeof value === 'number' && !isNaN(value)
    case 'boolean':
      return typeof value === 'boolean'
    case 'object':
      return typeof value === 'object' && value !== null && !Array.isArray(value)
    case 'array':
      return Array.isArray(value)
    case 'null':
      return value === null
    case 'undefined':
      return value === undefined
    case 'date':
      return value instanceof Date && !isNaN(value.getTime())
    case 'any':
      return true
    default:
      return false
  }
}

/**
 * 创建常用的验证模式
 */
export const schemas = {
  // 用户模式
  user: {
    required: ['username', 'email'],
    properties: {
      username: {
        type: 'string',
        minLength: 3,
        maxLength: 20,
        pattern: /^[a-zA-Z0-9_]+$/,
        message: '用户名只能包含字母、数字和下划线',
      },
      email: {
        type: 'string',
        pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
        message: '请输入有效的邮箱地址',
      },
      password: {
        type: 'string',
        minLength: 6,
        message: '密码长度至少为6位',
      },
      role: {
        type: 'string',
        enum: ['user', 'admin', 'editor'],
        default: 'user',
      },
      avatar: {
        type: 'string',
        default: '',
      },
      bio: {
        type: 'string',
        maxLength: 500,
        default: '',
      },
      isActive: {
        type: 'boolean',
        default: true,
      },
    },
  },

  // 视频模式
  video: {
    required: ['title', 'description', 'videoUrl'],
    properties: {
      title: {
        type: 'string',
        minLength: 1,
        maxLength: 200,
      },
      description: {
        type: 'string',
        minLength: 1,
      },
      videoUrl: {
        type: 'string',
        pattern: /^https?:\/\/.+$/,
        message: '请输入有效的视频URL',
      },
      thumbnailUrl: {
        type: 'string',
        default: '',
      },
      duration: {
        type: 'number',
        min: 0,
        default: 0,
      },
      category: {
        type: 'string',
        default: '',
      },
      tags: {
        type: 'array',
        items: {
          type: 'string',
        },
        default: [],
      },
      viewCount: {
        type: 'number',
        min: 0,
        default: 0,
      },
      likes: {
        type: 'number',
        min: 0,
        default: 0,
      },
      isPublished: {
        type: 'boolean',
        default: false,
      },
      publishedAt: {
        type: 'string',
        default: null,
      },
      authorId: {
        type: 'string',
        required: true,
      },
    },
  },

  // 标签模式
  tag: {
    required: ['name'],
    properties: {
      name: {
        type: 'string',
        minLength: 1,
        maxLength: 50,
      },
      color: {
        type: 'string',
        pattern: /^#[0-9A-F]{6}$/i,
        default: '#007bff',
      },
      usageCount: {
        type: 'number',
        min: 0,
        default: 0,
      },
    },
  },

  // 主题模式
  topic: {
    required: ['title'],
    properties: {
      title: {
        type: 'string',
        minLength: 1,
        maxLength: 100,
      },
      description: {
        type: 'string',
        default: '',
      },
      coverImage: {
        type: 'string',
        default: '',
      },
      videoIds: {
        type: 'array',
        items: {
          type: 'string',
        },
        default: [],
      },
      creatorId: {
        type: 'string',
        required: true,
      },
      isPublic: {
        type: 'boolean',
        default: true,
      },
    },
  },
}

/**
 * 验证ID格式
 * @param {string} id - 要验证的ID
 * @returns {boolean} 是否是有效的ID
 */
export function isValidId(id) {
  return typeof id === 'string' && id.length > 0 && /^[a-zA-Z0-9_\-]+$/.test(id)
}

/**
 * 清理数据，移除未定义的属性
 * @param {Object} data - 要清理的数据
 * @returns {Object} 清理后的数据
 */
export function sanitizeData(data) {
  if (!data || typeof data !== 'object') {
    return data
  }

  const sanitized = Array.isArray(data) ? [] : {}

  Object.keys(data).forEach(key => {
    if (data[key] !== undefined) {
      if (typeof data[key] === 'object' && data[key] !== null) {
        sanitized[key] = sanitizeData(data[key])
      } else {
        sanitized[key] = data[key]
      }
    }
  })

  return sanitized
}

/**
 * 转换数据为正确的类型
 * @param {Object} data - 要转换的数据
 * @param {Object} schema - 数据模式
 * @returns {Object} 转换后的数据
 */
export function convertDataTypes(data, schema) {
  if (!data || !schema || !schema.properties) {
    return data
  }

  const converted = { ...data }

  Object.keys(schema.properties).forEach(field => {
    if (converted.hasOwnProperty(field)) {
      const value = converted[field]
      const type = schema.properties[field].type

      switch (type) {
        case 'number':
          if (typeof value === 'string') {
            const num = parseFloat(value)
            if (!isNaN(num)) {
              converted[field] = num
            }
          }
          break
        case 'boolean':
          if (typeof value === 'string') {
            converted[field] = value.toLowerCase() === 'true'
          }
          break
        case 'array':
          if (typeof value === 'string') {
            try {
              converted[field] = JSON.parse(value)
            } catch (e) {
              // 如果解析失败，保持原样
            }
          }
          break
        case 'date':
          if (typeof value === 'string') {
            converted[field] = new Date(value).toISOString()
          }
          break
      }
    }
  })

  return converted
}